Crate bech32

source ·
Expand description

Encoding and decoding of the Bech32 format.

Bech32 is an encoding scheme that is easy to use for humans and efficient to encode in QR codes.

A Bech32 string consists of a human-readable part (HRP), a separator (the character '1'), and a data part. A checksum at the end of the string provides error detection to prevent mistakes when the string is written off or read out loud.

Usage

  • If you are doing segwit stuff you likely want to use the segwit API.
  • Non-segwit stuff and you have an allocator, use the top level API. For normal usage the encode and decode functions should suffice. There are also various other functions for explicit control of the checksum algorithm and the case used when encoding.
  • Non-segwit stuff and you do not have an allocator, use the primitives::decode::CheckedHrpstring type for decoding. For encoding we provide various top level functions of the form encode*_to_fmt.
  • To define your own checksum algorithm implement crate::Checksum (see example below).

The original description in BIP-0173 has more details. See also BIP-0350.

Examples

Encoding

use bech32::{hrp, segwit, Hrp, Bech32m};

const DATA: [u8; 20] = [0xab; 20]; // Arbitrary data to be encoded.
const ADDR: &str = "abc14w46h2at4w46h2at4w46h2at4w46h2at958ngu";
const TAP_ADDR: &str = "bc1p4w46h2at4w46h2at4w46h2at4w46h2at5kreae";

// Encode arbitrary data using "abc" as the human-readable part and append a bech32m checksum.
let hrp = Hrp::parse("abc").expect("valid hrp");
let address = bech32::encode::<Bech32m>(hrp, &DATA).expect("failed to encode address");
assert_eq!(address, ADDR);

// Encode arbitrary data as a Bitcoin taproot address.
let taproot_address = segwit::encode(&hrp::BC, segwit::VERSION_1, &DATA).expect("valid witness version and program");
assert_eq!(taproot_address, TAP_ADDR);

// No-alloc: Encode without allocating (ignoring that String::new() allocates :).
let mut buf = String::new();
bech32::encode_to_fmt::<Bech32m, String>(&mut buf, hrp, &DATA).expect("failed to encode to buffer");
assert_eq!(buf, ADDR);

Decoding

use bech32::primitives::decode::{CheckedHrpstring, SegwitHrpstring};
use bech32::{hrp, segwit, Hrp, Bech32m};

const DATA: [u8; 20] = [0xab; 20]; // Arbitrary data to be encoded.
const ADDR: &str = "abc14w46h2at4w46h2at4w46h2at4w46h2at958ngu";
const TAP_ADDR: &str = "bc1p4w46h2at4w46h2at4w46h2at4w46h2at5kreae";

// Decode a bech32 encoded string that includes a bech32/bech32m checksum.
//
// The input address MUST include a valid bech32 or bech32m checksum, for individual specific
// checksum algorithms see [`decode_bech32`], [`decode_bech32m`], [`decode_no_checksum`] or use
// the [`primitives::decode::CheckedHrpstring`] type directly.
let (hrp, data) = bech32::decode(&ADDR).expect("failed to decode");
assert_eq!(hrp, Hrp::parse("abc").unwrap());
assert_eq!(data, DATA);

// Decode a Bitcoin taproot address.
let (_hrp, _version, program) = segwit::decode(&TAP_ADDR).expect("valid address");
assert_eq!(program, DATA);

// No-alloc: Decode a bech32m checksummed address without allocating.
let p = CheckedHrpstring::new::<Bech32m>(&ADDR).expect("failed to parse address");
assert_eq!(hrp, p.hrp());
assert!(p.byte_iter().eq(DATA.iter().map(|&b| b))); // We yield bytes not references.

// No-alloc: Decode a taproot address without allocating.
let taproot = SegwitHrpstring::new(&TAP_ADDR).expect("valid address");
// Do something with the encoded data.
let _ = taproot.byte_iter();

Custom Checksum

use bech32::Checksum;

/// The codex32 checksum algorithm, defined in BIP-93.
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum Codex32 {}

impl Checksum for Codex32 {
    type MidstateRepr = u128;
    const CHECKSUM_LENGTH: usize = 13;
    // Copied from BIP-93
    const GENERATOR_SH: [u128; 5] = [
        0x19dc500ce73fde210,
        0x1bfae00def77fe529,
        0x1fbd920fffe7bee52,
        0x1739640bdeee3fdad,
        0x07729a039cfc75f5a,
    ];
    const TARGET_RESIDUE: u128 = 0x10ce0795c2fd1e62a;
}

Modules

  • Re-exports the hrp types from primitives::hrp to make importing ergonomic for the top level APIs.
  • All the primitive types and functionality used in encoding and decoding. Provides the internal nuts and bolts that enable bech32 encoding/decoding.
  • API for encoding and decoding segwit addresses. Segregated Witness API - enables typical usage for encoding and decoding segwit addresses.

Structs

  • An element in GF(32), the finite field containing elements [0,31] inclusive.
  • The human-readable part (human readable prefix before the ‘1’ separator).

Enums

Traits

  • Extension trait for byte iterators which provides an adaptor to GF32 elements.
  • Trait defining a particular checksum.
  • Extension trait for field element iterators.

Functions